#[derive(Debug, PartialEq)]
enum Flavor {
    Tea,
    Coffee,
    Juice,
    Water,
}

#[derive(Debug)]
struct Drink {
    flavor: Flavor,
    volume: i32,
    price: f64,
}

impl Drink {
    // 关联变量
    const SALE: f64 = 0.9;

    // 关联方法（实例）
    fn print(&self) {
        match self.flavor {
            Flavor::Tea => println!("tea"),
            Flavor::Coffee => println!("coffee"),
            Flavor::Juice => println!("juice"),
            Flavor::Water => println!("water"),
        }
    }

    // 关联方法（实例）
    fn buy(&self, money: f64) {
        if self.price == 0.0 && self.flavor == Flavor::Water {
            println!("free!");
            return;
        }

        if money >= self.price * Drink::SALE {
            println!("I can buy it");
            return;
        }

        println!("I can't buy it");
    }

    // 关联方法（结构体）
    fn free() -> Self {
        Drink {
            flavor: Flavor::Water,
            volume: 600,
            price: 0.0,
        }
    }

    fn sale(&self) {
        println!("price {}", self.price);
    }
}

// 元组结构体，不关联字段，只包含类型
#[derive(Debug)]
struct Tuple(i32, f64);
// 单元结构体，不用存数据
#[derive(Debug)]
struct Unit;
#[derive(Debug)]
struct Test {
    task1: i32,
    task2: f64,
}

fn main() {
    let juice = Drink {
        flavor: Flavor::Juice,
        volume: 330,
        price: 3.0,
    };
    juice.buy(5.0);
    juice.print();

    let water = Drink {
        flavor: Flavor::Water,
        volume: 600,
        price: 2.0,
    };
    water.buy(1.0);
    water.print();

    let water = Drink::free();
    water.buy(1.0);
    water.print();

    // 同名简写
    let price = 5.0;
    let juice = Drink {
        flavor: Flavor::Juice,
        volume: 330,
        price,
    };
    println!("Drink {:?}", juice);

    // 更新语法，在结构体末尾补充剩余字段，在原来的实例有字段失去了所有权，实例将不能被调用，实例下所有权没有被转移的字段可以继续使用（拥有Copy特质的类型，不会被转移所有权）
    let water1 = Drink {
        flavor: Flavor::Water,
        volume: 600,
        price: 3.0,
    };
    let water2 = Drink {
        price: 2.0,
        ..water1
    };
    // water1实例已失去所有权，下面调用，编译将不通过
    // println!("Drink {:?}", water1);
    println!("Drink {:?}", water2);

    println!("price {}", water1.price);
    println!("volume {}", water1.volume);
    // water1.flavor字段所有权已转移，无法调用，编译将通过
    // println!("flavor {:?}", water1.flavor);

    let t = Tuple(1, 2.0);
    println!("{:?}", t);

    let u = Unit;
    println!("{:?}", u);

    let test1 = Test{
      task1: 1,
      task2: 2.2
    };

    let test2 = Test{
      task1: 2,
      ..test1
    };

    println!("test1 {:?}", test1);
    println!("test2 {:?}", test2);
}
